package com.yunsc.system.service.impl;

import cn.hutool.crypto.digest.BCrypt;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yunsc.common.exception.YunscException;
import com.yunsc.common.utils.PageResult;
import com.yunsc.system.dao.YunscStoreMenuDao;
import com.yunsc.system.dao.YunscStoreRoleMenuDao;
import com.yunsc.system.dao.YunscStoreUserDao;
import com.yunsc.system.dao.YunscStoreUserRoleDao;
import com.yunsc.system.dto.QueryStoreUserDTO;
import com.yunsc.system.dto.StoreUserDTO;
import com.yunsc.system.entity.YunscStoreMenuEntity;
import com.yunsc.system.entity.YunscStoreRoleMenuEntity;
import com.yunsc.system.entity.YunscStoreUserEntity;
import com.yunsc.system.entity.YunscStoreUserRoleEntity;
import com.yunsc.system.service.YunscStoreUserRoleService;
import com.yunsc.system.service.YunscStoreUserService;
import com.yunsc.system.vo.StoreUserInfoVO;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;


@Service("yunscStoreUserService")
public class YunscStoreUserServiceImpl extends ServiceImpl<YunscStoreUserDao, YunscStoreUserEntity> implements YunscStoreUserService {

    @Resource
    private YunscStoreUserRoleDao storeUserRoleDao;
    @Resource
    private YunscStoreRoleMenuDao storeRoleMenuDao;

    @Resource
    private YunscStoreMenuDao storeMenuDao;
    @Resource
    private YunscStoreUserService storeUserService;
    @Resource
    private YunscStoreUserRoleService storeUserRoleService;

    // 获取用户信息
    @Override
    public StoreUserInfoVO getUserInfo(Integer userId, Integer storeId) {
        StoreUserInfoVO userInfoDto = new StoreUserInfoVO();
        YunscStoreUserEntity storeUser = this.getById(userId);
        storeUser.setPassword(null);
        userInfoDto.setUserInfo(storeUser);
        List<StoreUserInfoVO.Permission> permissionList = new ArrayList<>();
        if (storeUser.getIsSuper() != 1){
            // 获取用户权限
            YunscStoreUserRoleEntity userRoleEntity = storeUserRoleDao.selectOne(new LambdaQueryWrapper<YunscStoreUserRoleEntity>()
                    .eq(YunscStoreUserRoleEntity::getStoreUserId, userId));
            Integer roleId = userRoleEntity.getRoleId();
            // 获取角色对应菜单权限id
            List<YunscStoreRoleMenuEntity> storeRoleMenuList = storeRoleMenuDao.selectList(new LambdaQueryWrapper<YunscStoreRoleMenuEntity>()
                    .eq(YunscStoreRoleMenuEntity::getRoleId, roleId)
                    .eq(YunscStoreRoleMenuEntity::getStoreId, storeId));
            List<Integer> menuIds = storeRoleMenuList.stream().map(YunscStoreRoleMenuEntity::getMenuId).collect(Collectors.toList());
            // 获取角色对应菜单权限
            List<YunscStoreMenuEntity> menuList = storeMenuDao.selectBatchIds(menuIds);
            menuList.forEach(menu -> {
                StoreUserInfoVO.Permission permission = new StoreUserInfoVO.Permission();
                permission.setName(menu.getName());
                permission.setPermissionId(menu.getPath());
                permission.setActionEntitySet(getActionEntitySet(menu, menuList));
                if (StringUtils.isNotEmpty(menu.getPath())) {
                    permissionList.add(permission);
                }
            });
        }
        StoreUserInfoVO.Roles roles = new StoreUserInfoVO.Roles();
        roles.setIsSuper(storeUser.getIsSuper());
        roles.setPermissions(permissionList);
        userInfoDto.setRoles(roles);

        return userInfoDto;
    }

    // 查询店铺管理员列表
    @Override
    public PageResult<YunscStoreUserEntity> queryStoreUserList(QueryStoreUserDTO userParams, Integer storeId) {
        if (userParams == null) {
            userParams = new QueryStoreUserDTO();
        }
        Page<YunscStoreUserEntity> pageParam = new Page<>(userParams.getPage(), userParams.getPageSize());
        IPage<YunscStoreUserEntity> pageResult = this.baseMapper.queryStoreUserList(pageParam, userParams.getSearch(), storeId);
        return PageResult.formatPageResult(pageResult.getRecords(), userParams.getPage(), userParams.getPageSize(), pageResult.getTotal());
    }

    @Override
    @Transactional
    public void editStoreUser(StoreUserDTO userParams) {
        StoreUserDTO.StoreUserForm storeUserForm = userParams.getForm();
        String password = storeUserForm.getPassword();
        if (StringUtils.isNotEmpty(password) && !password.equals(storeUserForm.getPasswordConfirm())) {
            throw new YunscException("两次密码输入不一致");
        }
        Integer storeUserId = userParams.getUserId();
        YunscStoreUserEntity storeUserEntity = this.getById(storeUserId);
        if (storeUserEntity == null) {
            throw new YunscException("用户不存在");
        }
        BeanUtils.copyProperties(storeUserForm, storeUserEntity);
        storeUserEntity.setStoreUserId(storeUserId);
        // 密码加密
        String hashpwd = BCrypt.hashpw(password, BCrypt.gensalt());
        storeUserEntity.setPassword(hashpwd);
        boolean update = this.updateById(storeUserEntity);
        if (!update){
            throw new YunscException("编辑失败");
        }
        // 修改用户对应角色
        if (!CollectionUtils.isEmpty(storeUserForm.getRoles())){
            storeUserRoleService.editUserRole(storeUserId, storeUserForm.getRoles(), storeUserEntity.getStoreId());
        }
    }

    // 删除管理员用户
    @Override
    public void removeStoreUser(Integer userId) {
        // 软删除用户
        this.update(new UpdateWrapper<YunscStoreUserEntity>()
                .eq("store_user_id", userId).set("is_delete", 1));
        // 删除用户对应角色
        // storeUserRoleDao.delete(new LambdaQueryWrapper<YoshopStoreUserRoleEntity>()
        //         .eq(YoshopStoreUserRoleEntity::getStoreUserId, userId)
        //         .eq(YoshopStoreUserRoleEntity::getStoreId, storeId));
    }

    @Override
    @Transactional
    public void addStoreUser(StoreUserDTO storeUserDTO, Integer storeId) {
        StoreUserDTO.StoreUserForm storeUserForm = storeUserDTO.getForm();
        String userName = storeUserForm.getUserName();
        YunscStoreUserEntity storeUserEntity = this.getOne(new LambdaQueryWrapper<YunscStoreUserEntity>()
                .eq(YunscStoreUserEntity::getUserName, userName));
        if (storeUserEntity != null){
            throw new YunscException("用户名已存在");
        }
        String password = storeUserForm.getPassword();
        if (StringUtils.isEmpty(password) || !password.equals(storeUserForm.getPasswordConfirm())) {
            throw new YunscException("两次密码输入不一致");
        }
        storeUserEntity = new YunscStoreUserEntity();
        BeanUtils.copyProperties(storeUserForm, storeUserEntity);
        storeUserEntity.setStoreId(storeId);
        storeUserEntity.setIsSuper(0);
        // 密码加密
        String hashpwd = BCrypt.hashpw(password, BCrypt.gensalt());
        storeUserEntity.setPassword(hashpwd);

        this.save(storeUserEntity);
        // 新增用户对应角色
        storeUserRoleService.addUserRole(storeUserEntity.getStoreUserId(), storeUserForm.getRoles(), storeId);

    }

    @Override
    public void renewStoreUser(StoreUserDTO param, Integer storeUserId) {
        // 重置密码
        String password = param.getForm().getPassword();
        if (StringUtils.isEmpty(password) || !password.equals(param.getForm().getPasswordConfirm())) {
            throw new YunscException("两次密码输入不一致");
        }
        YunscStoreUserEntity storeUserEntity = this.getById(storeUserId);
        if (storeUserEntity == null) {
            throw new YunscException("用户不存在");
        }
        BeanUtils.copyProperties(param.getForm(), storeUserEntity);
        storeUserEntity.setStoreUserId(storeUserId);
        // 密码加密
        String hashpwd = BCrypt.hashpw(password, BCrypt.gensalt());
        storeUserEntity.setPassword(hashpwd);
        this.updateById(storeUserEntity);
    }


    // 获取菜单的actionEntitySet
    private List<StoreUserInfoVO.ChildPer> getActionEntitySet(YunscStoreMenuEntity menu, List<YunscStoreMenuEntity> menuList) {
        List<StoreUserInfoVO.ChildPer> actionEntitySet = new ArrayList<>();
        menuList.forEach(menuEntity -> {
            if (Objects.equals(menuEntity.getParentId(), menu.getMenuId())) {
                StoreUserInfoVO.ChildPer childPer = new StoreUserInfoVO.ChildPer();
                childPer.setAction(menuEntity.getActionMark());
                childPer.setDescribe(menuEntity.getName());
                actionEntitySet.add(childPer);
            }
        });
        return actionEntitySet;
    }


}